from django.shortcuts import render, redirect, get_object_or_404
from django.views import generic
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse
from django.http import JsonResponse
from django.db.models import Count

from .models import Book, Author, BookInstance, Genre, Review, Favorite, BookLike
from .forms import ReviewForm
from .recommender import get_recommendations_for_user, get_similar_books

def index(request):
    """
    View function for home page of site.
    """
    # Generate counts of some of the main objects
    num_books = Book.objects.all().count()
    num_instances = BookInstance.objects.all().count()
    # Available books (status = 'a')
    num_instances_available = BookInstance.objects.filter(status__exact='a').count()
    num_authors = Author.objects.count()  # The 'all()' is implied by default.
    
    # 获取评分排行榜前5名的书籍
    top_rated_books = Book.objects.filter(rating_count__gt=0).order_by('-rating')[:5]
    
    # 获取借阅排行榜前5名的书籍
    top_borrowed_books = Book.objects.annotate(borrow_count=Count('bookinstance')).order_by('-borrow_count')[:5]
    
    # 为已登录用户获取个性化推荐
    if request.user.is_authenticated:
        recommended_books = get_recommendations_for_user(request.user, count=4)
    else:
        recommended_books = None

    # Render the HTML template index.html with the data in the context variable
    return render(
        request,
        'index.html',
        context={
            'num_books': num_books,
            'num_instances': num_instances,
            'num_instances_available': num_instances_available,
            'num_authors': num_authors,
            'top_rated_books': top_rated_books,
            'top_borrowed_books': top_borrowed_books,
            'recommended_books': recommended_books,
        },
    )

class BookListView(generic.ListView):
    model = Book
    paginate_by = 10
    
    def get_queryset(self):
        queryset = Book.objects.all()
        
        # 分类筛选
        genre = self.request.GET.get('genre')
        if genre and genre != '所有类别':
            queryset = queryset.filter(genre__name=genre)
            
        # 排序
        sort_by = self.request.GET.get('sort_by')
        if sort_by:
            if sort_by == '评分最高':
                queryset = queryset.order_by('-rating')
            elif sort_by == '借阅最多':
                queryset = queryset.annotate(borrow_count=Count('bookinstance')).order_by('-borrow_count')
            elif sort_by == '最新上架':
                queryset = queryset.order_by('-id')  # 假设ID越大表示越新
                
        return queryset
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 添加类别列表供筛选
        context['genres'] = Genre.objects.all()
        # 获取当前筛选条件
        context['current_genre'] = self.request.GET.get('genre', '')
        context['current_sort'] = self.request.GET.get('sort_by', '')
        return context


class BookDetailView(generic.DetailView):
    model = Book
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        book = self.object
        context['reviews'] = book.reviews.all()
        
        # 相似书籍推荐
        context['similar_books'] = get_similar_books(book, count=4)
        
        # 检查用户是否已收藏和点赞
        if self.request.user.is_authenticated:
            context['is_favorite'] = Favorite.objects.filter(user=self.request.user, book=book).exists()
            context['is_liked'] = BookLike.objects.filter(user=self.request.user, book=book).exists()
            # 检查用户是否已评论
            context['user_reviewed'] = Review.objects.filter(user=self.request.user, book=book).exists()
            if context['user_reviewed']:
                context['user_review'] = Review.objects.get(user=self.request.user, book=book)
        
        # 添加评论表单
        context['form'] = ReviewForm()
        return context
        

class AuthorListView(generic.ListView):
    model = Author
    paginate_by = 10


class AuthorDetailView(generic.DetailView):
    model = Author
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['books'] = Book.objects.filter(author=self.object)
        return context


@login_required
def add_review(request, pk):
    book = get_object_or_404(Book, pk=pk)
    
    if request.method == 'POST':
        form = ReviewForm(request.POST)
        if form.is_valid():
            # 检查用户是否已经评论过这本书
            existing_review = Review.objects.filter(user=request.user, book=book).first()
            
            if existing_review:
                # 更新现有评论
                old_rating = existing_review.rating
                existing_review.comment = form.cleaned_data['comment']
                existing_review.rating = form.cleaned_data['rating']
                existing_review.save()
                
                # 更新书籍评分
                book.rating = book.rating - old_rating + form.cleaned_data['rating']
                book.save()
            else:
                # 创建新评论
                review = Review(
                    book=book,
                    user=request.user,
                    rating=form.cleaned_data['rating'],
                    comment=form.cleaned_data['comment']
                )
                review.save()
                
                # 更新书籍评分
                book.rating += form.cleaned_data['rating']
                book.rating_count += 1
                book.save()
                
    return redirect('book-detail', pk=pk)


@login_required
def toggle_favorite(request, pk):
    book = get_object_or_404(Book, pk=pk)
    favorite, created = Favorite.objects.get_or_create(user=request.user, book=book)
    
    if not created:
        # 如果已存在，则删除（取消收藏）
        favorite.delete()
        is_favorite = False
    else:
        is_favorite = True
    
    return JsonResponse({'is_favorite': is_favorite})


@login_required
def toggle_like(request, pk):
    book = get_object_or_404(Book, pk=pk)
    like, created = BookLike.objects.get_or_create(user=request.user, book=book)
    
    if not created:
        # 如果已存在，则删除（取消点赞）
        like.delete()
        book.likes -= 1
        is_liked = False
    else:
        # 新建，增加点赞数
        book.likes += 1
        is_liked = True
    
    book.save()
    return JsonResponse({'is_liked': is_liked, 'likes_count': book.likes})


# 用户的收藏列表
class UserFavoriteListView(LoginRequiredMixin, generic.ListView):
    model = Favorite
    template_name = 'catalog/user_favorites.html'
    paginate_by = 10
    
    def get_queryset(self):
        return Favorite.objects.filter(user=self.request.user)


# 排行榜视图
def ranking_list(request):
    # 评分排行
    top_rated = Book.objects.filter(rating_count__gt=0).order_by('-rating')[:10]
    
    # 借阅排行
    top_borrowed = Book.objects.annotate(borrow_count=Count('bookinstance')).order_by('-borrow_count')[:10]
    
    # 点赞排行
    top_liked = Book.objects.order_by('-likes')[:10]
    
    return render(
        request,
        'catalog/ranking_list.html',
        context={
            'top_rated': top_rated,
            'top_borrowed': top_borrowed,
            'top_liked': top_liked,
        }
    )


# 个人推荐页面
@login_required
def personal_recommendations(request):
    # 获取用户的个性化推荐
    recommended_books = get_recommendations_for_user(request.user, count=12)
    
    return render(
        request,
        'catalog/recommendations.html',
        {
            'recommended_books': recommended_books
        }
    )



